package com.thirteen.app.service.impl;

import com.thirteen.app.dao.*;
import com.thirteen.app.dto.CreateExamBySearchResponse.PaperSearchDto;
import com.thirteen.app.dto.CreateExamResponse.PaperInfoExamDto;
import com.thirteen.app.dto.CreatePaperResponse.PaperCreateDto;
import com.thirteen.app.dto.CreatePaperResponse.QuestionCreateDto;
import com.thirteen.app.dto.PaperListResponse.PaperListStudentDto;
import com.thirteen.app.dto.PaperWithAnswerResponse.PaperWithAnswerDto;
import com.thirteen.app.dto.PaperWithAnswerResponse.QuestionTypeWithAnswerDto;
import com.thirteen.app.dto.PaperWithAnswerResponse.QuestionWithAnswerDto;
import com.thirteen.app.dto.PaperWithScoreResponse.PaperWithScoreDto;
import com.thirteen.app.dto.PaperWithScoreResponse.QuestionTypeWithScoreDto;
import com.thirteen.app.dto.PaperWithScoreResponse.QuestionWithScoreDto;
import com.thirteen.app.dto.PaperListResponse.PaperListTeacherDto;
import com.thirteen.app.dto.PaperRespose.AnswerDto;
import com.thirteen.app.dto.PaperRespose.PaperDto;
import com.thirteen.app.dto.PaperRespose.QuestionDto;
import com.thirteen.app.dto.PaperRespose.QuestionTypeDto;
import com.thirteen.app.dto.PaperWithSolutionResponse.PaperWithSolutionDto;
import com.thirteen.app.dto.PaperWithSolutionResponse.QuestionTypeWithSolutionDto;
import com.thirteen.app.dto.PaperWithSolutionResponse.QuestionWithSolutionDto;
import com.thirteen.app.entity.ExamRecord;
import com.thirteen.app.entity.QuestionType;
import com.thirteen.app.service.PaperService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("paperService")
public class PaperServiceImpl implements PaperService {

    @Resource
    private PaperDao paperDao;

    @Resource
    private ExamDao examDao;

    @Resource
    private QuestionTypeDao questionTypeDao;

    @Resource
    private QuestionDao questionDao;

    @Resource
    private AnswerDao answerDao;

    @Resource
    private ExamRecordDao examRecordDao;

    @Resource
    private PaperSubjectiveDao paperSubjectiveDao;

    @Resource
    private PaperObjectiveDao paperObjectiveDao;

    @Resource
    private JudgeDao judgeDao;

    @Resource
    private QuestionTypeQuestionDao questionTypeQuestionDao;

    //    根据考试Id查出对应试卷
    @Override
    public PaperDto queryPaper(Integer examRecordId) {

        ExamRecord examRecord = examRecordDao.queryExamRecord(examRecordId);

        Integer totalTime = examDao.queryById(examRecord.getExamId()).getTotalTime() * 60;

        PaperDto paperDto = paperDao.queryPaper(examRecord.getPaperId());

        paperDto.setTotalTime(totalTime);

        paperDto.setExamRecordId(examRecordId);

        paperDto.setPaperQuestionTypesList(questionTypeDao.queryQuestionTypeDtoById(examRecord.getPaperId()));

        for (QuestionTypeDto i : paperDto.getPaperQuestionTypesList()) {
            i.setQuestionsList(questionDao.queryQuestionDto(i.getQuestionTypeId()));
            for (QuestionDto j : i.getQuestionsList()) {
                Integer questionId = j.getQuestionId();
                Integer questionType = i.getQuestionType();
                String answer = null;
                if (questionType == 1 || questionType == 3) {
                    answer = paperObjectiveDao.querySingleAndJudgeAnswer(examRecordId, questionId);
                    if (answer == null) {
                        answer = "";
                    }
                    j.setChoicesList(answerDao.querySelectionDto(questionId));
                } else if (questionType == 2) {
                    List<String> tmp = paperObjectiveDao.queryMultiAnswer(examRecordId, questionId);
                    if (tmp == null) {
                        answer = "";
                    } else {
                        answer = String.join(",", tmp);
                    }
                    j.setChoicesList(answerDao.querySelectionDto(questionId));
                } else if (questionType == 4 || questionType == 5) {
                    answer = paperSubjectiveDao.queryAnswer(examRecordId, questionId);
                }
                j.setAnswer(answer);
            }
        }
        return paperDto;
    }

    //    提交答案
    @Override
    public Boolean submitAnswer(AnswerDto answerDto) {
        switch (answerDto.getQuestionType()) {
            case 1:
                paperObjectiveDao.updateSingleAnswer(answerDto.getExamRecordId(), answerDto.getQuestionId(), answerDto.getAnswer());
                return true;
            case 2:
                paperObjectiveDao.cleanMultiAnswer(answerDto.getExamRecordId(), answerDto.getQuestionId());
                List<String> answer = Arrays.asList(answerDto.getAnswer().split(","));
                System.out.println(answer);
                for (String a : answer) {
                    paperObjectiveDao.updateMultiAnswer(answerDto.getExamRecordId(), answerDto.getQuestionId(), a);
                }
                return true;
            case 3:
                paperObjectiveDao.updateJudgeAnswer(answerDto.getExamRecordId(), answerDto.getQuestionId(), answerDto.getAnswer());
                return true;
            case 4:
            case 5:
                paperSubjectiveDao.submitAnswer(answerDto);
                return true;
        }
        return false;
    }

    //    交卷
    @Override
    public Boolean submitPaper(Integer examRecordId) {
        return examRecordDao.updateExamRecord(examRecordId);
    }

    //    查找试卷记录阅卷后有分数
    @Override
    public PaperWithScoreDto queryPaperWithScore(Integer examRecordId) {
        PaperWithScoreDto paperWithScoreDto = paperDao.queryPaperWithScore(examRecordId);
        paperWithScoreDto.setPaperQuestionTypesList(questionTypeDao.queryQuestionTypeWithScoreDtoById(examRecordDao.queryExamRecord(examRecordId).getPaperId()));
        for (QuestionTypeWithScoreDto i : paperWithScoreDto.getPaperQuestionTypesList()) {
            i.setQuestionsList(questionDao.queryQuestionWithScoreDto(i.getQuestionTypeId()));
            for (QuestionWithScoreDto j : i.getQuestionsList()) {
                Integer questionId = j.getQuestionId();
                Integer questionType = i.getQuestionType();
                String answer = null;
                String solution = null;
                if (questionType == 1 || questionType == 3) {
                    answer = paperObjectiveDao.querySingleAndJudgeAnswer(examRecordId, questionId);
                    if (answer == null) {
                        answer = "";
                    }
                    solution = answerDao.queryStandAnswer(questionId);
                    j.setChoicesList(answerDao.querySelectionDto(questionId));
                } else if (questionType == 2) {
                    List<String> answerTmp = paperObjectiveDao.queryMultiAnswer(examRecordId, questionId);
                    List<String> standAnswerTmp = answerDao.queryMultiStandAnswer(questionId);
                    if (answerTmp == null) {
                        answer = "";
                    } else {
                        answer = String.join(",", answerTmp);
                    }
                    solution = String.join(",", standAnswerTmp);
                    j.setChoicesList(answerDao.querySelectionDto(questionId));
                } else if (questionType == 4 || questionType == 5) {
                    answer = paperSubjectiveDao.queryAnswer(examRecordId, questionId);
                    solution = answerDao.queryCompletionAndShortAnswerStandAnswer(questionId);
                }
                j.setAnswer(answer);
                j.setSolution(solution);
                j.setActualScore(judgeDao.queryActualScore(examRecordId, questionId));
                j.setIsRight(judgeDao.queryQuestionIsRight(examRecordId, questionId));
            }
        }
        return paperWithScoreDto;
    }

    //    查找试卷记录有答案
    @Override
    public PaperWithAnswerDto queryPaperWithAnswer(Integer examRecordId) {
        Integer paperId = examRecordDao.queryExamRecord(examRecordId).getPaperId();
        PaperWithAnswerDto paperWithAnswerDto = paperDao.queryPaperWithAnswer(paperId);
        paperWithAnswerDto.setPaperQuestionTypesList(questionTypeDao.queryQuestionTypeWithAnswerDtoById(paperId));
        for (QuestionTypeWithAnswerDto i : paperWithAnswerDto.getPaperQuestionTypesList()) {
            i.setQuestionsList(questionDao.queryQuestionWithAnswerDto(i.getQuestionTypeId()));
            for (QuestionWithAnswerDto j : i.getQuestionsList()) {
                Integer questionId = j.getQuestionId();
                Integer questionType = i.getQuestionType();
                String answer = null;
                String solution = null;
                if (questionType == 1 || questionType == 3) {
                    answer = paperObjectiveDao.querySingleAndJudgeAnswer(examRecordId, questionId);
                    if (answer == null) {
                        answer = "";
                    }
                    solution = answerDao.queryStandAnswer(questionId);
                    j.setChoicesList(answerDao.querySelectionDto(questionId));
                } else if (questionType == 2) {
                    List<String> answerTmp = paperObjectiveDao.queryMultiAnswer(examRecordId, questionId);
                    List<String> standAnswerTmp = answerDao.queryMultiStandAnswer(questionId);
                    if (answerTmp == null) {
                        answer = "";
                    } else {
                        answer = String.join(",", answerTmp);
                    }
                    solution = String.join(",", standAnswerTmp);
                    j.setChoicesList(answerDao.querySelectionDto(questionId));
                } else if (questionType == 4 || questionType == 5) {
                    answer = paperSubjectiveDao.queryAnswer(examRecordId, questionId);
                    solution = answerDao.queryCompletionAndShortAnswerStandAnswer(questionId);
                }
                j.setAnswer(answer);
                j.setSolution(solution);
            }
        }
        return paperWithAnswerDto;
    }

    //    提供给管理员的试卷
    public PaperWithSolutionDto queryPaperWithSolution(Integer paperId){
        PaperWithSolutionDto paperWithSolutionDto = paperDao.queryPaperWithSolution(paperId);
        paperWithSolutionDto.setPaperQuestionTypesList(questionTypeDao.queryQuestionTypeWithSolutionDtoById(paperId));
        for (QuestionTypeWithSolutionDto i : paperWithSolutionDto.getPaperQuestionTypesList()) {
            i.setQuestionsList(questionDao.queryQuestionWithSolutionDto(i.getQuestionTypeId()));
            for (QuestionWithSolutionDto j : i.getQuestionsList()) {
                Integer questionId = j.getQuestionId();
                Integer questionType = i.getQuestionType();
                String solution = null;
                if (questionType == 1 || questionType == 3) {
                    solution = answerDao.queryStandAnswer(questionId);
                    j.setChoicesList(answerDao.querySelectionDto(questionId));
                } else if (questionType == 2) {
                    List<String> standAnswerTmp = answerDao.queryMultiStandAnswer(questionId);
                    solution = String.join(",", standAnswerTmp);
                    j.setChoicesList(answerDao.querySelectionDto(questionId));
                } else if (questionType == 4 || questionType == 5) {
                    solution = answerDao.queryCompletionAndShortAnswerStandAnswer(questionId);
                }
                j.setSolution(solution);
            }
        }
        return paperWithSolutionDto;
    }

    @Override
    public List<PaperSearchDto> queryAllPaperByCourseId(Integer courseId, String paperName, Integer offset, Integer limit) {
        return paperDao.queryAllPaperByCourseId(courseId, paperName, offset, limit);
    }

    @Override
    public PaperInfoExamDto queryPaperInfo(Integer paperId) {
        PaperInfoExamDto paperInfoExamDto = paperDao.queryPaperInfo(paperId);
        paperInfoExamDto.setUserName(paperDao.queryUserRealName(paperId));
        return paperInfoExamDto;
    }

    @Override
    public Boolean customCreatePaper(PaperCreateDto paperCreateDto) {
        Integer singleQuestionTypeId = null, multiQuestionTypeId = null, judgeQuestionTypeId = null, completionQuestionTypeId = null, shortQuestionTypeId = null;
        try {
        paperDao.insertPaperForCreate(paperCreateDto);
        Integer paperId = paperCreateDto.getPaperId();
        QuestionType questionType = new QuestionType();
        questionType.setPaperId(paperId);
        for (Integer i : paperCreateDto.getQuestionTypeList()) {
            questionType.setPaperId(paperId);
            questionType.setQuestionType(i);
            switch (i) {
                case 1:
                    questionType.setTitle("单选题");
                    questionTypeDao.insertQuestionTypeForCreate(questionType);
                    singleQuestionTypeId = questionType.getQuestionTypeId();
                    break;
                case 2:
                    questionType.setTitle("多选题");
                    questionTypeDao.insertQuestionTypeForCreate(questionType);
                    multiQuestionTypeId = questionType.getQuestionTypeId();
                    break;
                case 3:
                    questionType.setTitle("判断题");
                    questionTypeDao.insertQuestionTypeForCreate(questionType);
                    judgeQuestionTypeId = questionType.getQuestionTypeId();
                    break;
                case 4:
                    questionType.setTitle("填空题");
                    questionTypeDao.insertQuestionTypeForCreate(questionType);
                    completionQuestionTypeId = questionType.getQuestionTypeId();
                    break;
                case 5:
                    questionType.setTitle("简答题");
                    questionTypeDao.insertQuestionTypeForCreate(questionType);
                    shortQuestionTypeId = questionType.getQuestionTypeId();
                    break;
            }
        }
        for (QuestionCreateDto i : paperCreateDto.getQuestionList()) {
            switch (i.getQuestionType()) {
                case 1:
                    questionTypeQuestionDao.insertQuestionTypeQuestionForCreate(i.getQuestionId(), singleQuestionTypeId, i.getScore());
                    break;
                case 2:
                    questionTypeQuestionDao.insertQuestionTypeQuestionForCreate(i.getQuestionId(), multiQuestionTypeId, i.getScore());
                    break;
                case 3:
                    questionTypeQuestionDao.insertQuestionTypeQuestionForCreate(i.getQuestionId(), judgeQuestionTypeId, i.getScore());
                    break;
                case 4:
                    questionTypeQuestionDao.insertQuestionTypeQuestionForCreate(i.getQuestionId(), completionQuestionTypeId, i.getScore());
                    break;
                case 5:
                    questionTypeQuestionDao.insertQuestionTypeQuestionForCreate(i.getQuestionId(), shortQuestionTypeId, i.getScore());
                    break;
            }
        }
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    @Override
    public Boolean isMachineJudge(Integer examRecordId) {
        if (paperDao.isMachineJudge(examRecordId) == null) {
            return false;
        }
        return paperDao.isMachineJudge(examRecordId) == 0 ;
    }

    @Override
    public Map<String, Object> queryAllPaperByLimit(String paperName, String courseName, Integer offset, Integer limit) {
        Map<String, Object> map = new HashMap<>();
        map.put("list", this.paperDao.queryAllPaperByLimit(paperName,courseName,(offset - 1) * offset, limit));
        map.put("total", paperDao.getPaperCount());
        return map;
    }

    @Override
    public List<PaperListTeacherDto> queryPaperListTeacher(Integer userId){
        return paperDao.queryPaperListTeacher(userId);
    }

    @Override
    public Boolean deletePaper(Integer paperId){
        return paperDao.deletePaper(paperId);
    }

    @Override
    public Boolean judgePaperAuditAdmin(Integer paperId, Integer audit) {
        return paperDao.judgePaperAuditAdmin(paperId,audit);
    }

    @Override
    public Boolean applyPaperAuditTeacher(Integer paperId) {
        return paperDao.applyPaperAuditTeacher(paperId);
    }


}
